import { defineStore } from 'pinia'
import { useUserStore } from './user'
import { useRouter } from 'vue-router'
import request from '../utils/request'
import { ElMessage } from 'element-plus'

// 定义菜单项接口
export interface MenuItem {
  id: number
  pid: number
  title: string
  icon: string
  mig_src: string
  component: string
  redirect: string
  sort: number
  status: number
  children?: MenuItem[]
}

// 定义系统配置接口
export interface SystemConfig {
  id: number
  type: string
  code: string
  value: string
  title: string
  remark: string
  status: number
  create_time: number
  update_time: number
}

// 定义网站配置接口
export interface WebConfig {
  id: number
  code: string
  value: string
  name: string
  type: string
  sort: number
  status: number
  create_time: number
  update_time: number
}

// 定义管理员信息接口
export interface AdminInfo {
  id: number
  username: string
  name: string
  avatar: string
  department: string
  position: string
  role_ids: string
  rule_ids: string
  menu: MenuItem[]
}

// 定义菜单响应数据结构
export interface MenuResponseData {
  menu?: MenuItem[]
  admin?: AdminInfo
}

// 定义API响应接口
export interface ApiResponse<T = any> {
  code: number
  msg: string
  data: T
}

// 定义菜单状态管理接口
interface MenuState {
  menuList: MenuItem[]
  isMenuLoading: boolean
  activeMenu: string
  openedMenus: string[]
  systemConfigs: SystemConfig[]
  webConfigs: WebConfig[]
  isCollapse: boolean
  configLoading: boolean
}

// 菜单状态管理Store
export const useMenuStore = defineStore('menu', {
  state: (): MenuState => ({
    menuList: [],
    isMenuLoading: false,
    activeMenu: '/home',
    openedMenus: ['/home'],
    systemConfigs: [],
    webConfigs: [],
    isCollapse: false,
    configLoading: false,
  }),

  getters: {
    // 格式化菜单列表，添加路径前缀等处理
    formattedMenuList(): MenuItem[] {
      const menuStore = useMenuStore()

      const formatMenu = (menus: MenuItem[], parentPath = ''): MenuItem[] => {
        return menus.map(menu => {
          const formattedMenu: MenuItem = { ...menu }

          // 处理路径，添加父级路径前缀
          if (parentPath && menu.mig_src && !menu.mig_src.startsWith('/')) {
            formattedMenu.mig_src = `${parentPath}/${menu.mig_src}`
          }

          // 递归处理子菜单
          if (menu.children && menu.children.length > 0) {
            formattedMenu.children = formatMenu(menu.children, formattedMenu.mig_src)
          }

          return formattedMenu
        })
      }

      return formatMenu(menuStore.menuList)
    },
  },

  actions: {
    /**
     * 获取菜单路径
     * @param menu 菜单项
     * @returns 菜单项的完整路径
     */
    getMenuPath(menu: MenuItem): string {
      // 确保menu对象不为空
      if (!menu) return ''

      // 如果是重定向菜单，返回重定向地址
      if (menu.redirect && menu.redirect !== '#') {
        return menu.redirect
      }

      // 否则返回mig_src
      return menu.mig_src || ''
    },

    /**
     * 检查菜单列表是否有效
     * @param menuList 菜单列表
     * @returns 是否有效
     */
    isMenuListValid(menuList: MenuItem[]): boolean {
      try {
        // 基本检查
        if (!menuList || !Array.isArray(menuList) || menuList.length === 0) {
          return false
        }

        // 验证每个菜单项是否包含必要字段
        for (const menu of menuList) {
          if (!menu || typeof menu !== 'object') {
            return false
          }

          // 检查必要字段
          if (
            typeof menu.id !== 'number' ||
            typeof menu.title !== 'string' ||
            (menu.children && !Array.isArray(menu.children))
          ) {
            return false
          }

          // 递归验证子菜单
          if (menu.children && menu.children.length > 0) {
            if (!this.isMenuListValid(menu.children)) {
              return false
            }
          }
        }

        return true
      } catch (error) {
        return false
      }
    },

    /**
     * 检查是否为父级菜单
     * @param menu 菜单项
     * @returns 是否为父级菜单
     */
    isParentMenu(menu: MenuItem): boolean {
      // 确保menu对象不为空
      if (!menu) return false

      return !!(menu.children && menu.children.length > 0 && menu.mig_src === '')
    },

    /**
     * 设置当前激活的菜单
     * @param path 菜单项路径
     */
    setActiveMenu(path: string): void {
      this.activeMenu = path

      // 查找打开的菜单路径
      const getOpenPaths = (
        menu: MenuItem[],
        activePath: string,
        parents: string[] = []
      ): string[] => {
        for (const item of menu) {
          // 确保item对象不为空
          if (!item) continue

          const itemPath = this.getMenuPath(item)

          // 如果是当前路径，返回所有父级路径和当前路径
          if (itemPath === activePath) {
            return [...parents, itemPath]
          }

          // 如果有子菜单，递归查找
          if (item.children && item.children.length > 0) {
            const result = getOpenPaths(item.children, activePath, [...parents, itemPath])
            if (result.length > 0) {
              return result
            }
          }
        }
        return []
      }

      this.openedMenus = getOpenPaths(this.menuList, path)
    },

    /**
     * 更新已打开的菜单列表
     * @param menus 已打开的菜单路径列表
     */
    updateOpenedMenus(menus: string[]): void {
      this.openedMenus = menus
    },

    /**
     * 查找菜单路径
     * @param menu 菜单列表
     * @param path 目标路径
     * @param parents 父级路径列表
     * @returns 找到的路径列表
     */
    findMenuPath(menu: MenuItem[], path: string, parents: string[] = []): string[] {
      for (const item of menu) {
        // 确保item对象不为空
        if (!item) continue

        const itemPath = this.getMenuPath(item)

        // 如果是目标路径，返回所有父级路径和当前路径
        if (itemPath === path) {
          return [...parents, itemPath]
        }
        if (item.children) {
          const result: string[] = this.findMenuPath(item.children, path, [...parents, itemPath])
          if (result.length > 0) return result
        }
      }
      return []
    },

    /**
     * 根据当前路由设置激活菜单
     */
    setActiveMenuByRoute(currentPath?: string) {
      // 如果没有传入路径，则使用默认路径
      const path = currentPath || '/home'
      const menuStore = useMenuStore()

      // 检查路径是否存在于菜单中
      const existsInMenu = (menus: MenuItem[], path: string): boolean => {
        for (const menu of menus) {
          // 添加对menu对象的检查，确保它不是undefined
          if (!menu) continue

          // 如果是父级菜单，只检查子菜单
          if (this.isParentMenu(menu)) {
            if (existsInMenu(menu.children || [], path)) {
              return true
            }
            continue
          }

          const menuPath = menuStore.getMenuPath(menu)
          if (menuPath === path) {
            return true
          }
          if (menu.children && existsInMenu(menu.children, path)) {
            return true
          }
        }
        return false
      }

      if (existsInMenu(this.menuList, path)) {
        this.setActiveMenu(path)
      } else {
        // 设置默认菜单为工作台
        this.setActiveMenu('/home')
      }
    },

    /**
     * 加载菜单列表 - 优化后的版本
     * 修复要点:
     * 1. 优先使用localStorage缓存,减少重复请求
     * 2. 确保用户信息和菜单数据同步加载
     * 3. 只有当缓存无效时才重新请求
     * @param forceRefresh 是否强制刷新菜单数据
     * @returns 加载是否成功
     */
    async loadMenuList(forceRefresh = false): Promise<boolean> {
      try {
        this.isMenuLoading = true
        if (forceRefresh) localStorage.removeItem('menuList')
        if (!forceRefresh && this.menuList.length > 0) return true

        // 步骤1: 尝试从 localStorage 加载缓存
        const cachedMenu = localStorage.getItem('menuList')
        if (cachedMenu && !forceRefresh) {
          try {
            const menuCache = JSON.parse(cachedMenu)
            if (
              menuCache?.menuList?.length > 0 &&
              menuCache.menuList.some((item: MenuItem) => item.id !== -1)
            ) {
              this.menuList = menuCache.menuList
              this.setActiveMenu('/home')
              return true
            }
          } catch (e) {
            localStorage.removeItem('menuList')
          }
        }

        // 步骤2: 检查 userStore 中是否有用户信息
        const userStore = useUserStore()
        if (!userStore.userInfo?.id) {
          const cached = localStorage.getItem('userInfo')
          if (cached) {
            try {
              const userInfoObj = JSON.parse(cached)
              if (userInfoObj?.id > 0) userStore.userInfo = userInfoObj
            } catch (e) {}
          }
        }

        const workbenchMenu: MenuItem = {
          id: -1,
          pid: 0,
          title: '工作台',
          icon: 'HomeFilled',
          mig_src: '/home',
          component: '',
          redirect: '',
          sort: 0,
          status: 1,
        }

        // 步骤3: 如果用户信息中包含菜单，使用该菜单
        if (
          userStore.userInfo &&
          userStore.userInfo.menu &&
          Array.isArray(userStore.userInfo.menu) &&
          userStore.userInfo.menu.length > 0
        ) {
          this.menuList = [workbenchMenu, ...userStore.userInfo.menu]
          this.setActiveMenu('/home')
          this.cacheMenuList()
          return true
        }

        // 步骤4: 从后端获取菜单数据
        try {
          const menuResponse: any = await request.get('/api/system/menu')
          if (menuResponse?.code === 0 && menuResponse.data?.length > 0) {
            this.menuList = [workbenchMenu, ...menuResponse.data]
            if (userStore.userInfo) {
              ;(userStore.userInfo as any).menu = menuResponse.data
              localStorage.setItem('userInfo', JSON.stringify(userStore.userInfo))
            }
          } else {
            this.menuList = [workbenchMenu]
          }
        } catch (error) {
          this.menuList = [workbenchMenu]
        }

        this.setActiveMenu('/home')
        this.cacheMenuList()
        return true
      } catch (error) {
        this.setMinimalMenuData()
        return true
      } finally {
        this.isMenuLoading = false
      }
    },

    /**
     * 设置最小化菜单数据（仅包含工作台）
     */
    setMinimalMenuData(): void {
      const workbenchMenu: MenuItem = {
        id: -1,
        pid: 0,
        title: '工作台',
        icon: 'HomeFilled',
        mig_src: '/home',
        component: '',
        redirect: '',
        sort: 0,
        status: 1,
      }

      this.menuList = [workbenchMenu]
      this.setActiveMenu('/home')
      // 不缓存最小化菜单数据
    },

    /**
     * 获取模拟菜单数据
     * @returns 模拟的菜单数据数组
     */
    getMockMenuData(): MenuItem[] {
      // 返回空数组，不再提供模拟菜单
      return []
    },

    /**
     * 设置模拟菜单数据
     * 注意：此方法已被废弃，不会再设置模拟菜单数据
     */
    setMockMenuData(): void {
      this.setMinimalMenuData()
    },

    /**
     * 缓存菜单列表到localStorage
     */
    cacheMenuList(): void {
      try {
        // 只在有真实菜单数据时缓存
        if (this.menuList.length > 1) {
          const menuDataToCache = {
            menuList: this.menuList,
            timestamp: Date.now(),
          }
          localStorage.setItem('menuList', JSON.stringify(menuDataToCache))
        }
      } catch (e) {}
    },

    /**
     * 更新单个菜单项的属性
     * @param menuId 菜单项ID
     * @param updates 要更新的属性对象
     * @returns 是否更新成功
     */
    updateMenuItem(menuId: number, updates: Partial<MenuItem>): boolean {
      try {
        // 递归查找并更新菜单项
        const updateMenuRecursive = (menus: MenuItem[]): boolean => {
          for (let i = 0; i < menus.length; i++) {
            const menu = menus[i]

            if (menu.id === menuId) {
              // 找到匹配的菜单项，更新属性
              menus[i] = { ...menu, ...updates }
              return true
            }

            // 如果有子菜单，递归查找
            if (menu.children && menu.children.length > 0) {
              if (updateMenuRecursive(menu.children)) {
                return true
              }
            }
          }
          return false
        }

        // 更新菜单列表
        const updated = updateMenuRecursive(this.menuList)

        // 如果更新成功，更新缓存
        if (updated) {
          this.cacheMenuList()
        }

        return updated
      } catch (error) {
        return false
      }
    },

    /**
     * 根据ID查找菜单项
     * @param menuId 菜单项ID
     * @returns 找到的菜单项或null
     */
    findMenuItemById(menuId: number): MenuItem | null {
      try {
        // 递归查找菜单项
        const findMenuRecursive = (menus: MenuItem[]): MenuItem | null => {
          for (const menu of menus) {
            if (menu.id === menuId) {
              return menu
            }

            // 如果有子菜单，递归查找
            if (menu.children && menu.children.length > 0) {
              const found = findMenuRecursive(menu.children)
              if (found) {
                return found
              }
            }
          }
          return null
        }

        return findMenuRecursive(this.menuList)
      } catch (error) {
        return null
      }
    },
  },
})
